package cn.yh.nft.turbo.chain.facade;

import cn.yh.nft.turbo.api.chain.constant.ChainType;
import cn.yh.nft.turbo.api.chain.request.ChainProcessRequest;
import cn.yh.nft.turbo.api.chain.response.ChainProcessResponse;
import cn.yh.nft.turbo.api.chain.response.data.ChainCreateData;
import cn.yh.nft.turbo.api.chain.response.data.ChainOperationData;
import cn.yh.nft.turbo.api.chain.service.ChainFacadeService;
import cn.yh.nft.turbo.chain.domain.service.ChainService;
import cn.yh.nft.turbo.chain.domain.service.ChainServiceFactory;
import cn.yh.nft.turbo.rpc.facade.Facade;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import static cn.yh.nft.turbo.base.constant.ProfileConstant.PROFILE_DEV;

/**
 * @ClassName: ChainFacadeServiceImpl
 * @Author: 草莓爱上啵啵
 */
@DubboService(version = "1.0.0")
public class ChainFacadeServiceImpl implements ChainFacadeService {

    @Value("${nft.turbo.chain.type:MOCK}")
    private String chainType;

    @Value("${spring.profiles.active}")
    private String profile;

    @Autowired
    private ChainServiceFactory chainServiceFactory;

    /**
     * 创建地址的接口方法
     * 该方法用于处理链地址的创建请求，是对外提供的一个接口
     *
     * @param request 包含创建地址所需信息的请求对象
     * @return 返回一个包含链创建数据的响应对象
     */
    @Override
    @Facade
    public ChainProcessResponse<ChainCreateData> createAddr(ChainProcessRequest request) {
        // 调用链服务的创建地址方法，处理请求并返回响应
        return getChainService().createAddr(request);
    }

    /**
     * 重写父类的铸币方法，用于处理链上铸币操作
     * 该方法通过门面注解标记，以便在外部系统中进行调用
     *
     * @param request 包含链上铸币所需数据的请求对象
     * @return 返回链上操作数据的响应对象
     */
    @Override
    @Facade
    public ChainProcessResponse<ChainOperationData> mint(ChainProcessRequest request) {
        // 调用链服务的铸币方法，并返回结果
        return getChainService().mint(request);
    }

    /**
     * 转账操作的实现方法
     *
     * 此方法接收一个链式处理请求对象，并将其转发给链式服务进行处理
     * 使用了@Override注解来表明这是在重写父类或接口的方法
     * @Facade注解表明这是一个外观方法，用于隐藏系统的复杂性，提供简单的接口
     *
     * @param request 链式处理请求对象，包含了转账操作所需的数据和上下文
     * @return 返回链式处理响应对象，包含了转账操作的结果和可能的附加数据
     */
    @Override
    @Facade
    public ChainProcessResponse<ChainOperationData> transfer(ChainProcessRequest request) {
        return getChainService().transfer(request);
    }

    /**
     * 重写父类方法，执行销毁操作
     * 该方法通过ChainProcessRequest对象接收请求参数，并调用链式服务的销毁方法
     *
     * @param request 包含销毁操作所需数据的请求对象
     * @return 返回包含销毁操作结果数据的响应对象
     */
    @Override
    @Facade
    public ChainProcessResponse<ChainOperationData> destroy(ChainProcessRequest request) {
        return getChainService().destroy(request);
    }

    /**
     * 获取链服务根据当前配置
     *
     * 此方法根据当前的配置信息来选择合适的链服务类型如果当前配置为开发环境，
     * 则返回模拟链服务；否则，根据配置的链类型返回相应的链服务
     *
     * @return ChainService 实例，根据配置的链类型提供服务
     */
    private ChainService getChainService(){
        // 判断当前配置是否为开发环境
        if (PROFILE_DEV.equals(profile) ){
            // 在开发环境下，使用模拟链服务
            return chainServiceFactory.get(ChainType.MOCK);
        }

        // 根据配置的链类型获取相应的链服务
        ChainService chainService = chainServiceFactory.get(ChainType.valueOf(chainType));
        // 返回链服务实例
        return chainService;
    }

    /**
     * 重写链式处理方法，用于执行链式操作
     *
     * @param request 链式处理请求对象，包含链式操作所需的数据
     * @return 返回链式处理的响应对象，包含操作结果
     *
     * 此方法通过调用链式服务的同名方法来执行链式操作，目的是为了实现业务逻辑的链式处理
     * 使用 @Facade 注解表明这是一个外观方法，隐藏了内部系统的复杂性
     */
    @Override
    @Facade
    public ChainProcessResponse<ChainOperationData> chain(ChainProcessRequest request) {
        return getChainService().chain(request);
    }
}
